import tkinter as tk
from tkinter import ttk,messagebox
import pandas as pd
import os

def center_window(window, width, height):
    # 获取屏幕宽度和高度
    screen_width = window.winfo_screenwidth()
    screen_height = window.winfo_screenheight()

    # 计算窗口左上角坐标
    x = (screen_width / 2) - (width / 2)
    y = (screen_height / 2) - (height / 2)

    # 设置窗口位置
    window.geometry(f'{width}x{height}+{int(x)}+{int(y)}')
    
class TableApp:
    def __init__(self, root):
        self.root = root
        self.root.title("增删改查")
        center_window(self.root, 600, 400)

        # 设置ttk主题
        style = ttk.Style(root)
        style.theme_use('clam')  # 可以选择 'clam', 'alt', 'default', 'classic' 等
        style.configure('TButton', font=('Helvetica', 12), foreground='blue')
        style.configure('Red.TButton', font=('Helvetica', 12), foreground='red') # 红色按钮
        style.configure('TLabel', font=('Helvetica', 12), foreground='black')
        style.configure('TEntry', font=('Helvetica', 12))
        style.configure('TCheckBox', font=('Helvetica', 12))
        
        # 创建一个DataFrame来存储数据
        self.projects = pd.DataFrame(columns=['Name', 'Path'])
        self.projectNames = []
        self.currentProject = ''
        if os.path.exists('projects.csv'):
            self.projects = pd.read_csv('projects.csv') 
            self.projects['Name']=self.projects['Name'].astype(str)
            self.projectNames = self.projects['Name'].values.tolist()
            #print(self.projectNames)
            #print(self.projects)
            
        self.data = pd.DataFrame(columns=['Name', 'Age', 'Gender'])

        ttk.Label(root, text="项目").grid(row=0, column=0, padx=10, pady=5, sticky="w")
        self.combo = ttk.Combobox(root, values=self.projectNames,state="readonly")
        self.combo.grid(row=0, column=1, padx=10, pady=5, sticky="w")
        
        # 绑定选择事件
        self.combo.bind("<<ComboboxSelected>>", self.on_com_select)              
        
        self.labelInfo = ttk.Label(root, text=".")
        self.labelInfo.grid(row=0, column=2, padx=10, pady=5, sticky="w")
               
        # 创建表格
        self.tree = ttk.Treeview(root, columns=('Name', 'Age', 'Gender'), show='headings')
        self.tree.heading('Name', text='Name')
        self.tree.heading('Age', text='Age')
        self.tree.heading('Gender', text='Gender')
        self.tree.grid(row=1, column=0, columnspan=4, padx=10, pady=10, sticky="nsew")

        # 绑定选中事件
        self.tree.bind('<<TreeviewSelect>>', self.on_tree_select)

        # 创建输入框
        self.name_var = tk.StringVar()
        self.age_var = tk.StringVar()
        self.gender_var = tk.StringVar()

        ttk.Label(root, text="Name").grid(row=2, column=0, padx=10, pady=5, sticky="w")
        self.name_entry = ttk.Entry(root, textvariable=self.name_var)
        self.name_entry.grid(row=2, column=1, padx=10, pady=5, sticky="w")

        ttk.Label(root, text="Age").grid(row=3, column=0, padx=10, pady=5, sticky="w")
        self.age_entry = ttk.Entry(root, textvariable=self.age_var)
        self.age_entry.grid(row=3, column=1, padx=10, pady=5, sticky="w")

        ttk.Label(root, text="Gender").grid(row=4, column=0, padx=10, pady=5, sticky="w")
        self.gender_entry = ttk.Entry(root, textvariable=self.gender_var)
        self.gender_entry.grid(row=4, column=1, padx=10, pady=5, sticky="w")

        self.isNewProject = tk.IntVar()
        # 创建两个复选框
        self.checkbox1 = tk.Checkbutton(root, text="修改", variable=self.isNewProject, onvalue=1, offvalue=0, command=self.on_checkbox_change)
        self.checkbox1.grid(row=4, column=3, padx=10, pady=5, sticky="w")
         
        # 创建按钮
        self.add_button = ttk.Button(root, text="Add", command=self.add_item)
        self.add_button.grid(row=5, column=0, padx=10, pady=10, sticky="w")

        self.update_button = ttk.Button(root, text="Update", command=self.update_item)
        self.update_button.grid(row=5, column=1, padx=10, pady=10, sticky="w")

        self.delete_button = ttk.Button(root, text="Delete", command=self.delete_item)
        self.delete_button.grid(row=5, column=2, padx=10, pady=10, sticky="w")
        
        self.save_button = ttk.Button(root, text="Save",style='Red.TButton', command=self.save_item)
        self.save_button.grid(row=5, column=3, padx=10, pady=10, sticky="w")

        # 配置列和行的权重
        root.columnconfigure(0, weight=1)
        root.columnconfigure(1, weight=1)
        root.columnconfigure(2, weight=1)
        root.columnconfigure(3, weight=1)
        root.rowconfigure(1, weight=1)

        # 默认选中最后一项
        projectCount = len(self.projectNames)
        if projectCount > 0:     
            self.combo.current(projectCount-1)
            self.on_com_select(None)
        else: # 没有项目数据时 设置为 新增模式
            self.isNewProject.set(1)
            self.checkbox1.config(state='disabled')
    
    # 清空列表
    def clear_treeview(self):
        for item in self.tree.get_children():
            self.tree.delete(item)
    
    # 新增 | 修改模式切换
    def on_checkbox_change(self):
        if self.isNewProject.get() == 1:
            self.checkbox1.config(text='新增')
        else:
            self.checkbox1.config(text='修改')
    
    def on_com_select(self,event):
        #print("Combobox selected")
        #print(event)
        value = self.combo.get()
        self.currentProject = self.projects.query('Name == @value').iat[0,1]
        self.labelInfo.config (text = self.currentProject)
        #print(self.projects[self.projects['Name']==value])
        #print(self.projects[self.projects['Name']==value]['Path'][0])
        #print(f"你选择了: {value}")
        self.load_data()
    
    # 默认选中行
    def selectRow(self,row=0):
        items = self.tree.get_children()    
        if items :
            self.tree.selection_set(items[row])
    
    # 选中行后的回调函数
    def on_tree_select(self, event):
        selecteditems = self.tree.selection()  # 获取选中的行
        if selecteditems: 
            values = self.tree.item(selecteditems[0], 'values')  # 获取选中行的值
            self.name_var.set(values[0])
            self.age_var.set(values[1])
            self.gender_var.set(values[2])

    # 加载数据
    def load_data(self):
        if os.path.exists(self.currentProject):
            self.data = pd.read_csv(self.currentProject) 
        self.clear_treeview()
        for index, row in self.data.iterrows():
            self.tree.insert('', 'end', values=(row['Name'], row['Age'], row['Gender']))
        self.selectRow()
    
    # 保存新项目数据
    def saveNewProjectData(self):
        global popup, entry  # 声明全局变量
        # 创建一个新的Toplevel窗口
        popup = tk.Toplevel(self.root)
        popup.title("新建项目")
        center_window(popup, 400, 100)
        
        # 设置子窗口为模态 (主窗口不能点击的效果)
        popup.transient(self.root)
        popup.grab_set()

        # 在子窗口中添加一些内容
        label = ttk.Label(popup, text="名称")
        label.grid(row=0, column=0, padx=10, pady=5, sticky="w")
        
        entry = tk.Entry(popup,width=40)
        entry.grid(row=0, column=1,columnspan=3, padx=10, pady=10, sticky="w")
        
        # 添加一个确定按钮
        ok_button = ttk.Button(popup, text="确定", command=self.sub_on_ok)
        ok_button.grid(row=1, column=1, padx=10, pady=10, sticky="w")

        # 添加一个取消按钮
        close_button = ttk.Button(popup, text="取消", command=popup.destroy)
        close_button.grid(row=1, column=2, padx=10, pady=10, sticky="w")
        
        popup.columnconfigure(0, weight=2)
        popup.columnconfigure(1, weight=3)
        popup.columnconfigure(2, weight=3)
        popup.columnconfigure(3, weight=2)
        
    # 修改当前项目数据
    def editProjectData(self):        
         self.data.to_csv(self.currentProject, index=False) # 测试 保存数据到 csv 文件
        
    # 保存数据到 csv
    def save_item(self):
        if self.isNewProject.get() == 1: # 新增
            self.saveNewProjectData()
        else: # 修改
            self.editProjectData()
            
    def sub_on_ok(self):        
        result = entry.get()
        # 同名的项目是否已存在 需要提醒
        pds = self.projects.query('Name == @result')
        if pds.empty == False: # 非空 表示 同名项目已存在
            messagebox.showerror("错误", "同名的项目已存在！")
            return
        
        retPath='data\\'+result+'.csv'
        self.data.to_csv(retPath, index=False) # 测试 保存数据到 csv 文件
        new_row = pd.DataFrame({'Name': [result], 'Path': [retPath]})        
        self.projects = pd.concat([self.projects, new_row], ignore_index=True)
        self.projects.to_csv('projects.csv', index=False) # 测试 保存数据到 csv 文件
        popup.destroy()
    
    # 添加一行
    def add_item(self):
        name = self.name_var.get()
        age = self.age_var.get()
        gender = self.gender_var.get()
        new_row = pd.DataFrame({'Name': [name], 'Age': [age], 'Gender': [gender]})
        self.data = pd.concat([self.data, new_row], ignore_index=True)
        self.tree.insert('', 'end', values=(name, age, gender))

    # 更新选中的行
    def update_item(self):
        selected_item = self.tree.selection()
        if selected_item:
            name = self.name_var.get()
            age = self.age_var.get()
            gender = self.gender_var.get()
            self.tree.item(selected_item, values=(name, age, gender))
            index = self.tree.index(selected_item)
            self.data.at[index, 'Name'] = name
            self.data.at[index, 'Age'] = age
            self.data.at[index, 'Gender'] = gender

    # 删除选中的行
    def delete_item(self):
        selected_item = self.tree.selection()
        if selected_item:
            index = self.tree.index(selected_item)
            self.tree.delete(selected_item)
            self.data.drop(index, inplace=True)
            self.data.reset_index(drop=True, inplace=True)
            if index < len(self.data):
                self.selectRow(index)
            else:
                self.selectRow(len(self.data)-1)

if __name__ == "__main__":
    if os.path.exists('data') == False:
        os.mkdir('data')
    root = tk.Tk()
    app = TableApp(root)
    root.mainloop()
